package gridmapper;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.plaf.ComponentUI;
import org.dom4j.Document;
import org.dom4j.DocumentException;

/**
 *
 * @author estell
 */
public class MapPanel extends javax.swing.JPanel implements KeyListener, MouseListener, MouseMotionListener {

	private static ArrayList<GridSpace[]> mapList = new ArrayList<GridSpace[]>();
	private static int mapWidth = 0;
	private static int mapHeight = 0;
	private String tileType = "building";
	private String mapFileName = "";
	private BufferedImage bufferedTileSheet;
	private MasterImage imageLink;
	private int startX, startY; // Point where mouse is pressed.
	private int prevX, prevY;   // Most recently processed mouse coords.
	private boolean dragging;   // Set to true when dragging is in process.
	private boolean showGrid = true;
	private ResourceBundle mapTileProps;
	private ResourceBundle globalProps;
	private int tileHeight;
	private int tileWidth;

	public int getTileHeight() {
		return tileHeight;
	}

	public void setTileHeight(int tileHeight) {
		this.tileHeight = tileHeight;
	}

	public int getTileWidth() {
		return tileWidth;
	}

	public void setTileWidth(int tileWidth) {
		this.tileWidth = tileWidth;
	}

	public boolean isShowGrid() {
		return showGrid;
	}

	public void setShowGrid(boolean showGrid) {
		this.showGrid = showGrid;
	}

	public BufferedImage getBufferedTileSheet() {
		return bufferedTileSheet;
	}

	public void setBufferedTileSheet(BufferedImage bufferedTileSheet) {
		this.bufferedTileSheet = bufferedTileSheet;
	}

	public MasterImage getImageLink() {
		return imageLink;
	}

	public void setImageLink(MasterImage imageLink) {
		this.imageLink = imageLink;
	}

	public ResourceBundle getRb() {
		return mapTileProps;
	}

	public void setRb(ResourceBundle rb) {
		this.mapTileProps = rb;
	}

	public MapPanel() {
		initComponents();
		globalProps = ResourceBundle.getBundle("gridmapper/Application");
	}

	public void buildNewMap(int width, int height) {
		try {
			AppUtils utils = new AppUtils();
			mapList = utils.buildNewMap(width, height);
			mapHeight = height * tileHeight;
			mapWidth = width * tileWidth;

			System.out.println("WIDTH (COLS)" + mapWidth);
			System.out.println("HEIGHT (ROWS) " + mapHeight);

			Dimension dim = new Dimension(mapWidth, mapHeight);
			this.setPreferredSize(dim);
			this.setMinimumSize(dim);
			this.setMaximumSize(dim);

			if (bufferedTileSheet == null) {
				bufferedTileSheet = ImageIO.read(new File(globalProps.getString("globalImagePath") + globalProps.getString("defaultTileSheet")));
			}
		} catch (Exception ex) {
			Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
		}
	}

	/**
	 * Stub method for JIA integration. May or may not be needed
	 */
	public void buildJiaMap(){
		//GNDN
	}

	public void buildMap(String thisFileName) {
		MapBuilder builder = new MapBuilder();
		File myFile = new File(thisFileName);
		try {

			Document doc = builder.parse(myFile);
			mapList = builder.buildMap(doc, 1);
			String resourceName = builder.getAssignedMapResourceName(doc, 1);
			mapTileProps = ResourceBundle.getBundle("images/" + resourceName);
			tileHeight = Integer.parseInt(mapTileProps.getString("tileHeight"));
			tileWidth = Integer.parseInt(mapTileProps.getString("tileWidth"));

			mapHeight = builder.getMapHeight(doc, 1) * tileHeight;
			mapWidth = builder.getMapWidth(doc, 1) * tileWidth;

			System.out.println("WIDTH (COLS)" + mapWidth);
			System.out.println("HEIGHT (ROWS) " + mapHeight);

			Dimension dim = new Dimension(mapWidth, mapHeight);
			this.setPreferredSize(dim);
			this.setMinimumSize(dim);
			this.setMaximumSize(dim);
			this.addMouseListener(this);
			this.addMouseMotionListener(this);
			this.addKeyListener(this);

			if (bufferedTileSheet == null) {
				bufferedTileSheet = ImageIO.read(new File("resources/images/" + resourceName + ".png"));
			}
		} catch (DocumentException ex) {
			Logger.getLogger(MapPanel.class.getName()).log(Level.SEVERE, null, ex);
		} catch (IOException ex) {
		}
	}

	public String getMapFileName() {
		return mapFileName;
	}

	public void setMapFileName(String mapFileName) {
		this.mapFileName = mapFileName;
	}

	public static int getMapHeight() {
		return mapHeight;
	}

	public static void setMapHeight(int mapHeight) {
		MapPanel.mapHeight = mapHeight;
	}

	public static ArrayList<GridSpace[]> getMapList() {
		return mapList;
	}

	public static void setMapList(ArrayList<GridSpace[]> mapList) {
		MapPanel.mapList = mapList;
	}

	public static int getMapWidth() {
		return mapWidth;
	}

	public static void setMapWidth(int mapWidth) {
		MapPanel.mapWidth = mapWidth;
	}

	public String getTileType() {
		return tileType;
	}

	public void setTileType(String tileType) {
		this.tileType = tileType;
	}

	public ComponentUI getUi() {
		return ui;
	}

	public void setUi(ComponentUI ui) {
		this.ui = ui;
	}

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		AppUtils imgUtils = new AppUtils();
		//loop the y axis (rows)
		if (mapList != null) {
			for (int i = 0; i < mapList.size(); i++) {
				GridSpace[] spcArry = mapList.get(i);
				//loop the x axis(columns)
				for (int j = 0; j < spcArry.length; j++) {
					GridSpace spc = spcArry[j];

					if (spc.getType().equals(Constants.Type.TYPE_FOREST)) {
						g.setColor(new Color(79, 79, 47));
						g.drawImage(imgUtils.getTileImage(bufferedTileSheet, mapTileProps, Constants.Type.TYPE_FOREST, spc.getSubtype()), j * tileHeight, i * tileWidth, tileWidth, tileHeight, null);
					} else if (spc.getType().equals(Constants.Type.TYPE_ROCK)) {
						g.setColor(Color.LIGHT_GRAY);
						g.fillRect(j * tileHeight, i * tileWidth, tileWidth, tileHeight);
						g.drawImage(imgUtils.getTileImage(bufferedTileSheet, mapTileProps, Constants.Type.TYPE_LIQUID, spc.getSubtype()), j * tileHeight, i * tileWidth, tileWidth, tileHeight, null);

					} else if (spc.getType().equals(Constants.Type.TYPE_PATH)) {
						g.setColor(Color.YELLOW);
						g.fillRect(j * tileHeight, i * tileWidth, tileWidth, tileHeight);
						g.drawImage(imgUtils.getTileImage(bufferedTileSheet, mapTileProps, Constants.Type.TYPE_PATH, spc.getSubtype()), j * tileHeight, i * tileWidth, tileWidth, tileHeight, null);


					} else if (spc.getType().equals(Constants.Type.TYPE_JUNGLE)) {
						g.setColor(Color.YELLOW);
						g.fillRect(j * tileHeight, i * tileWidth, tileWidth, tileHeight);
						g.drawImage(imgUtils.getTileImage(bufferedTileSheet, mapTileProps, Constants.Type.TYPE_JUNGLE, spc.getSubtype()), j * tileHeight, i * tileWidth, tileWidth, tileHeight, null);


					} else if (spc.getType().equals(Constants.Type.TYPE_LIQUID)) {
						g.setColor(Color.BLUE);
						g.fillRect(j * tileHeight, i * tileWidth, tileWidth, tileHeight);
						g.drawImage(imgUtils.getTileImage(bufferedTileSheet, mapTileProps, Constants.Type.TYPE_LIQUID, spc.getSubtype()), j * tileHeight, i * tileWidth, tileWidth, tileHeight, null);

					} else if (spc.getType().equals(Constants.Type.TYPE_GROUND)) {
						g.setColor(Color.GREEN);
						g.fillRect(j * tileHeight, i * tileWidth, tileWidth, tileHeight);
						g.drawImage(imgUtils.getTileImage(bufferedTileSheet, mapTileProps, Constants.Type.TYPE_GROUND, spc.getSubtype()), j * tileHeight, i * tileWidth, tileWidth, tileHeight, null);

					} else if (spc.getType().equals(Constants.Type.TYPE_BUILDING)) {
						g.setColor(Color.BLACK);
						g.fillRect(j * tileHeight, i * tileWidth, tileWidth, tileHeight);
						g.drawImage(imgUtils.getTileImage(bufferedTileSheet, mapTileProps, Constants.Type.TYPE_GROUND, spc.getSubtype()), j * tileHeight, i * tileWidth, tileWidth, tileHeight, null);
						g.drawImage(imgUtils.getTileImage(bufferedTileSheet, mapTileProps, Constants.Type.TYPE_BUILDING, spc.getSubtype()), j * tileHeight, i * tileWidth, tileWidth, tileHeight, null);
					} else {
						g.setColor(Color.RED);
						g.fillRect(j * tileHeight, i * tileWidth, tileWidth, tileHeight);
					}
				}

			}

			if (showGrid) {
				int grid;
				int gridWidth = 0;
				g.setColor(Color.WHITE);
				// draw the rows
				for (grid = 0; grid < mapList.size(); grid++) {
					gridWidth = mapList.get(0).length;
					g.drawLine(0, grid * tileHeight, mapWidth, grid * tileHeight);
				}

				for (grid = 0; grid < gridWidth; grid++) {
					g.drawLine(grid * tileWidth, 0, grid * tileWidth, mapHeight);
				}
			}

		}
	}

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPopupMenu1 = new javax.swing.JPopupMenu();
        jMenuItem1 = new javax.swing.JMenuItem();

        jMenuItem1.setText("jMenuItem1");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        jPopupMenu1.add(jMenuItem1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 550, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

	private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
		// TODO add your handling code here:
	}//GEN-LAST:event_jMenuItem1ActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JPopupMenu jPopupMenu1;
    // End of variables declaration//GEN-END:variables
	public void keyTyped(KeyEvent e) {
		//GNDN
	}

	public void keyPressed(KeyEvent e) {
		//GNDN
	}

	public void keyReleased(KeyEvent e) {
		//GNDN
	}

	public void mouseClicked(MouseEvent e) {
		//GNDN
	}

	public void mousePressed(MouseEvent e) {

		if (e.getButton() == MouseEvent.BUTTON1){
			dragging = true;
			startX = e.getX();  // Remember starting position.
			startY = e.getY();
			prevX = startX;       // Remember most recent coords.
			prevY = startY;

			int gridx = e.getX() / tileWidth;
			int gridy = e.getY() / tileHeight;

			GridSpace[] arry = mapList.get(gridy);
			GridSpace spc = arry[gridx];

			spc.setType(imageLink.getSelectedType());
			spc.setSubtype(imageLink.getSubtype());

			this.repaint();

		}else if (e.getButton() == MouseEvent.BUTTON2 || e.getButton() == MouseEvent.BUTTON3){
			System.out.println("Button 2 Pressed");
			
				this.jPopupMenu1.show(e.getComponent(),e.getX(),e.getY());				



		}


	}

	public void mouseReleased(MouseEvent e) {
		if (dragging == false) { // First, check if we are processing a dragging gesture.
			return;
		}
		// We are done dragging.
		dragging = false;
	}

	public void mouseEntered(MouseEvent e) {
		//GNDN
	}

	public void mouseExited(MouseEvent e) {
		//GNDN
	}

	public void mouseDragged(MouseEvent e) {
		if (dragging == false) // First, check if we are
		{
			return;               //   processing a dragging gesture.
		}
		int x = e.getX(); // Current position of Mouse.
		int y = e.getY();

		int gridx = e.getX() / tileWidth;
		int gridy = e.getY() / tileHeight;
		GridSpace[] arry = mapList.get(gridy);
		GridSpace spc = arry[gridx];

		spc.setType(imageLink.getSelectedType());
		spc.setSubtype(imageLink.getSubtype());

		this.repaint();
		prevX = x;  // Remember the current position for the next call.
		prevY = y;

	}

	public void mouseMoved(MouseEvent e) {
		//GNDN
	}
}
